library(ironmarch)
library(dplyr)
library(igraph)
library(ggplot2)

print.data.table <- function(x) print(tibble::as_tibble(x))
print.data.frame <- function(x) print(tibble::as_tibble(x))

extract_ego <- function(g, ego_name, n_steps = 1L) {
  hood <- unlist(neighborhood(
    g,
    order = n_steps,
    nodes = which(vertex_attr(g, "screen_name") == ego_name)
  ), use.names = FALSE)

  induced_subgraph(g, hood)
}

vis_net <- function(ego_g, ego_name = NULL) {
  if (!is.null(ego_name) && ego_name %in% vertex_attr(ego_g, "screen_name")) {
    vertex_attr(ego_g, "color", 
                which(vertex_attr(ego_g, "screen_name") == ego_name)) <- "red"
  }
  edge_attr(ego_g, "title") <- edge_attr(ego_g, "msg_post")
  suppressWarnings(visNetwork::visIgraph(ego_g)) %>%
    visNetwork::visOptions(nodesIdSelection = TRUE, highlightNearest = TRUE)
}

igraph_options(print.full = FALSE)
build_members()
## # A tibble: 1,542 x 83
##    member_id name  member_group_id email joined              ip_address
##        <int> <chr>           <int> <chr> <dttm>              <chr>     
##  1         1 Алек…               4 slav… 2011-09-12 15:46:59 178.140.1…
##  2         2 Phal…              13 illu… 2011-09-12 15:52:30 68.37.21.…
##  3         3 Bloo…              13 rene… 2011-09-12 18:10:11 68.10.255…
##  4         4 Mier…              13 homi… 2011-09-12 20:27:35 82.29.169…
##  5         5 Will…              14 tash… 2011-09-12 20:58:17 90.214.15…
##  6         7 Dadd…              13 benj… 2011-09-13 01:22:58 81.141.31…
##  7         8 Mr. …              13 elei… 2011-09-13 04:24:07 98.198.24…
##  8         9 Woma…              14 sol.… 2011-09-13 10:27:52 88.147.27…
##  9        11 Four…              13 o244… 2011-09-13 12:14:28 109.77.91…
## 10        12 Jami…              14 jami… 2011-09-13 17:43:02 86.134.81…
## # … with 1,532 more rows, and 77 more variables: allow_admin_mails <lgl>,
## #   skin <int>, warn_level <int>, warn_lastwarn <int>, restrict_post <lgl>,
## #   bday_day <int>, bday_month <int>, bday_year <int>, msg_count_new <int>,
## #   msg_count_total <int>, msg_show_notification <lgl>, last_visit <dttm>,
## #   last_activity <dttm>, mod_posts <lgl>, auto_track <chr>, temp_ban <lgl>,
## #   mgroup_others <chr>, member_login_key_expire <dttm>,
## #   members_seo_name <chr>, members_cache <chr>, members_disable_pm <int>,
## #   failed_logins <chr>, members_profile_views <int>, members_pass_hash <chr>,
## #   members_pass_salt <chr>, members_bitoptions <int>, members_day_posts <chr>,
## #   notification_cnt <int>, posts <int>, title <chr>, time_offset <chr>,
## #   last_post <dttm>, view_sigs <lgl>, msg_count_reset <lgl>, dst_in_use <lgl>,
## #   login_anonymous <chr>, ignored_users <chr>, org_perm_id <chr>,
## #   member_login_key <chr>, members_auto_dst <lgl>, members_display_name <chr>,
## #   members_l_display_name <chr>, members_l_username <chr>,
## #   member_banned <lgl>, member_uploader <chr>, language <int>,
## #   failed_login_count <int>, pp_last_visitors <chr>, pp_main_photo <chr>,
## #   pp_main_width <int>, pp_main_height <int>, pp_thumb_photo <chr>,
## #   pp_thumb_width <int>, pp_thumb_height <int>,
## #   pp_setting_count_comments <lgl>, pp_reputation_points <int>,
## #   pp_gravatar <chr>, pp_photo_type <chr>, signature <chr>,
## #   fb_bwoptions <lgl>, tc_last_sid_import <chr>, tc_bwoptions <lgl>,
## #   pp_customization <chr>, timezone <chr>, pp_cover_photo <chr>,
## #   members_bitoptions2 <int>, create_menu <chr>, marked_site_read <int>,
## #   pp_cover_offset <int>, acp_skin <lgl>, acp_language <lgl>,
## #   member_title <chr>, member_posts <int>, member_last_post <int>,
## #   member_streams <chr>, photo_last_update <dttm>, msg_count_reset_at <dttm>
build_messages()
## # A tibble: 22,309 x 8
##    msg_id msg_topic_id msg_date            msg_post msg_post_key msg_author_id
##     <int>        <int> <dttm>              <chr>    <chr>                <int>
##  1      1            1 2011-09-16 03:49:58 "<p>The… 3320f7f06c4…             1
##  2      2            2 2011-09-16 11:54:08 "\n<p>W… 9204e488332…            11
##  3      3            2 2011-09-16 14:39:59 "<p>Cri… 12fd0309239…             1
##  4      4            2 2011-09-16 15:29:01 "<p>Tha… 0658c6f99ac…            11
##  5      5            2 2011-09-16 15:32:58 "<p>If … 570257864e3…             1
##  6      6            2 2011-09-16 15:44:51 "<p>The… aabeacc8f4c…            11
##  7      7            3 2011-09-17 01:43:49 "<p>I d… a36f67c0d72…            16
##  8      8            3 2011-09-17 01:59:50 "\n<blo… 327b933d818…            14
##  9     12            5 2011-09-20 14:20:14 "<p>The… 0667258c387…             1
## 10     13            5 2011-09-20 14:42:17 "<p>Don… de1d7fd2737…            20
## # … with 22,299 more rows, and 2 more variables: msg_ip_address <chr>,
## #   msg_is_first_post <lgl>

Enrichment/Reference Data

im_personnel
## # A tibble: 44 x 8
##    name  real_name member_id affiliation sources aka   possible_aka was_military
##    <chr> <chr>         <int> <list>      <list>  <lis> <chr>        <lgl>       
##  1 TheW… Devon Ar…      9304 <chr [2]>   <chr [… <chr… <NA>         NA          
##  2 Woma… <NA>              9 <chr [1]>   <chr [… <chr… <NA>         NA          
##  3 Mr. … <NA>              8 <chr [1]>   <chr [… <chr… <NA>         NA          
##  4 Figl… <NA>             37 <chr [1]>   <chr [… <chr… <NA>         NA          
##  5 Алек… <NA>              1 <chr [1]>   <chr [… <chr… Alisher Muk… NA          
##  6 Odin  Brandon …      7600 <chr [1]>   <chr [… <chr… <NA>         TRUE        
##  7 The … David Co…      6249 <chr [1]>   <chr [… <chr… <NA>         TRUE        
##  8 Arat… <NA>           9869 <chr [1]>   <chr [… <chr… <NA>         NA          
##  9 Stea… <NA>          13092 <chr [1]>   <chr [… <chr… <NA>         NA          
## 10 <NA>  Nicholas…        NA <chr [1]>   <chr [… <chr… <NA>         NA          
## # … with 34 more rows
im_groups
## # A tibble: 16 x 2
##    name                                       aka      
##    <chr>                                      <list>   
##  1 Atomwaffen Division                        <chr [2]>
##  2 International Third Positionist Federation <chr [1]>
##  3 Nordic Resistance Movement                 <chr [1]>
##  4 National Democratic Party of Germany       <chr [1]>
##  5 Golden Dawn                                <chr [1]>
##  6 Gromada                                    <chr [1]>
##  7 Young Russian Socialist Avantgarde         <chr [1]>
##  8 National Action                            <chr [1]>
##  9 American Vanguard                          <chr [1]>
## 10 Traditionalist Workers Party               <chr [1]>
## 11 Silver Legion                              <chr [1]>
## 12 Azov Battalion                             <chr [3]>
## 13 Feuerkrieg Division                        <chr [1]>
## 14 Generation WAR                             <chr [1]>
## 15 Vorherrschaft Division                     <chr [1]>
## 16 Aryan Underground                          <chr [1]>
im_events
## # A tibble: 7 x 4
##   name                        category date       start_time         
##   <chr>                       <chr>    <date>     <dttm>             
## 1 November 2015 Paris attacks attack   2015-11-13 2015-11-13 19:16:00
## 2 2011 Norway attack          attack   2011-07-22 NA                 
## 3 Sandy Hook                  attack   2012-12-14 NA                 
## 4 Las Vegas Shooting          attack   2017-10-01 2017-10-01 15:05:00
## 5 Pulse Nightclub Shooting    attack   2016-06-12 2016-06-11 19:02:00
## 6 San Bernadino attack        attack   2012-12-02 2012-12-02 02:58:00
## 7 Isla Vista killings         attack   2014-05-23 2014-05-23 14:27:00
g <- im_message_network()
print(g, full = FALSE)
## IGRAPH 3ea3745 U--- 821 41786 -- 
## + attr: member_id (v/n), screen_name (v/c), member_group_id (v/n),
## | email (v/c), ip_address (v/c), allow_admin_mails (v/l), skin (v/n),
## | warn_level (v/n), warn_lastwarn (v/n), restrict_post (v/l), bday_day
## | (v/n), bday_month (v/n), bday_year (v/n), msg_count_new (v/n),
## | msg_count_total (v/n), msg_show_notification (v/l), mod_posts (v/l),
## | auto_track (v/c), temp_ban (v/l), mgroup_others (v/c),
## | members_seo_name (v/c), members_cache (v/c), members_disable_pm
## | (v/n), failed_logins (v/c), members_profile_views (v/n),
## | members_pass_hash (v/c), members_pass_salt (v/c), members_bitoptions
## | (v/n), members_day_posts (v/c), notification_cnt (v/n), posts (v/n),
## | title (v/c), time_offset (v/c), last_post (v/n), view_sigs (v/l),
## | msg_count_reset (v/l), dst_in_use (v/l), login_anonymous (v/c),
## | ignored_users (v/c), org_perm_id (v/c), member_login_key (v/c),
## | members_auto_dst (v/l), members_display_name (v/c),
## | members_l_display_name (v/c), members_l_username (v/c), member_banned
## | (v/l), member_uploader (v/c), language (v/n), failed_login_count
## | (v/n), pp_last_visitors (v/c), pp_main_photo (v/c), pp_main_width
## | (v/n), pp_main_height (v/n), pp_thumb_photo (v/c), pp_thumb_width
## | (v/n), pp_thumb_height (v/n), pp_setting_count_comments (v/l),
## | pp_reputation_points (v/n), pp_gravatar (v/c), pp_photo_type (v/c),
## | signature (v/c), fb_bwoptions (v/l), tc_last_sid_import (v/c),
## | tc_bwoptions (v/l), pp_customization (v/c), timezone (v/c),
## | pp_cover_photo (v/c), members_bitoptions2 (v/n), create_menu (v/c),
## | marked_site_read (v/n), pp_cover_offset (v/n), acp_skin (v/l),
## | acp_language (v/l), member_title (v/c), member_posts (v/n),
## | member_last_post (v/n), member_streams (v/c), photo_last_update
## | (v/n), msg_count_reset_at (v/n), source_msg_author_id (e/n),
## | target_msg_author_id (e/n), msg_topic_id (e/n), msg_id (e/n),
## | msg_date (e/n), msg_post (e/c), msg_author_id (e/n), msg_ip_address
## | (e/c), msg_is_first_post (e/l)
edge_density(g)
## [1] 0.1241377
g %>% degree() %>% mean()
## [1] 101.7929

Node Table

tibble::as_tibble(vertex_attr(g))
## # A tibble: 821 x 79
##    member_id screen_name member_group_id email ip_address allow_admin_mai…  skin
##        <int> <chr>                 <int> <chr> <chr>      <lgl>            <int>
##  1         1 Александр …               4 slav… 178.140.1… FALSE                0
##  2         2 PhalNat                  13 illu… 68.37.21.… TRUE                 0
##  3         3 Blood and …              13 rene… 68.10.255… TRUE                 0
##  4         4 Mierce                   13 homi… 82.29.169… FALSE                0
##  5         5 Will to Po…              14 tash… 90.214.15… TRUE                 0
##  6         7 Daddy Terr…              13 benj… 81.141.31… TRUE                 0
##  7         8 Mr. Elegy                13 elei… 98.198.24… TRUE                 0
##  8         9 Woman in B…              14 sol.… 88.147.27… FALSE                0
##  9        11 Four Suite…              13 o244… 109.77.91… FALSE                0
## 10        12 Jamie M                  14 jami… 86.134.81… TRUE                 0
## # … with 811 more rows, and 72 more variables: warn_level <int>,
## #   warn_lastwarn <int>, restrict_post <lgl>, bday_day <int>, bday_month <int>,
## #   bday_year <int>, msg_count_new <int>, msg_count_total <int>,
## #   msg_show_notification <lgl>, mod_posts <lgl>, auto_track <chr>,
## #   temp_ban <lgl>, mgroup_others <chr>, members_seo_name <chr>,
## #   members_cache <chr>, members_disable_pm <int>, failed_logins <chr>,
## #   members_profile_views <int>, members_pass_hash <chr>,
## #   members_pass_salt <chr>, members_bitoptions <int>, members_day_posts <chr>,
## #   notification_cnt <int>, posts <int>, title <chr>, time_offset <chr>,
## #   last_post <dttm>, view_sigs <lgl>, msg_count_reset <lgl>, dst_in_use <lgl>,
## #   login_anonymous <chr>, ignored_users <chr>, org_perm_id <chr>,
## #   member_login_key <chr>, members_auto_dst <lgl>, members_display_name <chr>,
## #   members_l_display_name <chr>, members_l_username <chr>,
## #   member_banned <lgl>, member_uploader <chr>, language <int>,
## #   failed_login_count <int>, pp_last_visitors <chr>, pp_main_photo <chr>,
## #   pp_main_width <int>, pp_main_height <int>, pp_thumb_photo <chr>,
## #   pp_thumb_width <int>, pp_thumb_height <int>,
## #   pp_setting_count_comments <lgl>, pp_reputation_points <int>,
## #   pp_gravatar <chr>, pp_photo_type <chr>, signature <chr>,
## #   fb_bwoptions <lgl>, tc_last_sid_import <chr>, tc_bwoptions <lgl>,
## #   pp_customization <chr>, timezone <chr>, pp_cover_photo <chr>,
## #   members_bitoptions2 <int>, create_menu <chr>, marked_site_read <int>,
## #   pp_cover_offset <int>, acp_skin <lgl>, acp_language <lgl>,
## #   member_title <chr>, member_posts <int>, member_last_post <int>,
## #   member_streams <chr>, photo_last_update <dttm>, msg_count_reset_at <dttm>

Edge Table

tibble::as_tibble(igraph::edge_attr(g))
## # A tibble: 41,786 x 9
##    source_msg_auth… target_msg_auth… msg_topic_id msg_id msg_date           
##               <int>            <int>        <int>  <int> <dttm>             
##  1                1               11            2      2 2011-09-16 11:54:08
##  2               11                1            2      2 2011-09-16 11:54:08
##  3                1               11            2      3 2011-09-16 14:39:59
##  4               11                1            2      3 2011-09-16 14:39:59
##  5                1               11            2      4 2011-09-16 15:29:01
##  6               11                1            2      4 2011-09-16 15:29:01
##  7                1               11            2      5 2011-09-16 15:32:58
##  8               11                1            2      5 2011-09-16 15:32:58
##  9                1               11            2      6 2011-09-16 15:44:51
## 10               11                1            2      6 2011-09-16 15:44:51
## # … with 41,776 more rows, and 4 more variables: msg_post <chr>,
## #   msg_author_id <int>, msg_ip_address <chr>, msg_is_first_post <lgl>

Ego Extraction

target_node <- "Blood and Iron"

ego_g <- g %>%
  extract_ego(ego_name = target_node, n_steps = 1)

vcount(ego_g)
## [1] 17
ecount(ego_g)
## [1] 494
ego_g %>%
  vis_net(ego_name = target_node)
ego_g_member_names <- vertex_attr(ego_g, "screen_name")
ego_g_member_names
##  [1] "PhalNat"                   "Blood and Iron"           
##  [3] "Mierce"                    "Daddy Terror"             
##  [5] "Four Suited Jack"          "Jamie M"                  
##  [7] "Mortimer"                  "Figlio di Moros"          
##  [9] "With Hate As My Sword"     "Chadislav Thunderkokovich"
## [11] "FascistCapitalist"         "SchwarzFrontUSA"          
## [13] "Vanguard"                  "FasciNation"              
## [15] "Max Renn"                  "jotunn"                   
## [17] "Steinkopf"

Spatial Data

all_members_sf <- im_geocode_members() %>% filter(!is.na(member_id))
plot(all_members_sf$geometry)

all_members_sf
## Simple feature collection with 1542 features and 94 fields
## geometry type:  POINT
## dimension:      XY
## bbox:           xmin: -157.8028 ymin: -54.8076 xmax: 176.162 ymax: 69.6513
## CRS:            EPSG:4326
## # A tibble: 1,542 x 95
##    member_id name  member_group_id email joined              ip_address
##  *     <int> <chr>           <int> <chr> <dttm>              <chr>     
##  1         1 Алек…               4 slav… 2011-09-12 15:46:59 178.140.1…
##  2       191 Ms.R…              13 yith… 2012-03-26 19:39:57 69.245.18…
##  3      9475 meng…              13 azmh… 2015-05-10 09:57:19 5.228.66.…
##  4      9288 Змај…               6 flam… 2015-03-08 22:09:26 87.116.15…
##  5      9510 TheD…              13 bill… 2015-05-31 23:08:49 86.15.81.…
##  6        49 Влад…              14 vlad… 2011-10-04 23:15:18 71.185.16…
##  7       164 Yori…              13 74e8… 2012-02-24 17:28:50 134.88.17…
##  8      1074 Guy …              13 theb… 2012-10-10 20:47:36 81.151.20…
##  9      1109 Leon…              13 uber… 2012-10-15 22:42:11 212.10.14…
## 10       319 Sif                13 sawa… 2012-07-14 11:25:21 174.49.12…
## # … with 1,532 more rows, and 89 more variables: allow_admin_mails <lgl>,
## #   skin <int>, warn_level <int>, warn_lastwarn <int>, restrict_post <lgl>,
## #   bday_day <int>, bday_month <int>, bday_year <int>, msg_count_new <int>,
## #   msg_count_total <int>, msg_show_notification <lgl>, last_visit <dttm>,
## #   last_activity <dttm>, mod_posts <lgl>, auto_track <chr>, temp_ban <lgl>,
## #   mgroup_others <chr>, member_login_key_expire <dttm>,
## #   members_seo_name <chr>, members_cache <chr>, members_disable_pm <int>,
## #   failed_logins <chr>, members_profile_views <int>, members_pass_hash <chr>,
## #   members_pass_salt <chr>, members_bitoptions <int>, members_day_posts <chr>,
## #   notification_cnt <int>, posts <int>, title <chr>, time_offset <chr>,
## #   last_post <dttm>, view_sigs <lgl>, msg_count_reset <lgl>, dst_in_use <lgl>,
## #   login_anonymous <chr>, ignored_users <chr>, org_perm_id <chr>,
## #   member_login_key <chr>, members_auto_dst <lgl>, members_display_name <chr>,
## #   members_l_display_name <chr>, members_l_username <chr>,
## #   member_banned <lgl>, member_uploader <chr>, language <int>,
## #   failed_login_count <int>, pp_last_visitors <chr>, pp_main_photo <chr>,
## #   pp_main_width <int>, pp_main_height <int>, pp_thumb_photo <chr>,
## #   pp_thumb_width <int>, pp_thumb_height <int>,
## #   pp_setting_count_comments <lgl>, pp_reputation_points <int>,
## #   pp_gravatar <chr>, pp_photo_type <chr>, signature <chr>,
## #   fb_bwoptions <lgl>, tc_last_sid_import <chr>, tc_bwoptions <lgl>,
## #   pp_customization <chr>, timezone <chr>, pp_cover_photo <chr>,
## #   members_bitoptions2 <int>, create_menu <chr>, marked_site_read <int>,
## #   pp_cover_offset <int>, acp_skin <lgl>, acp_language <lgl>,
## #   member_title <chr>, member_posts <int>, member_last_post <int>,
## #   member_streams <chr>, photo_last_update <dttm>, msg_count_reset_at <dttm>,
## #   status <chr>, country <chr>, countryCode <chr>, region <chr>,
## #   regionName <chr>, city <chr>, zip <chr>, i.timezone <chr>, isp <chr>,
## #   org <chr>, as <chr>, geometry <POINT [°]>
all_members_sf %>%
  mapview::mapview()

Spatial Ego Extraction

all_members_sf %>% 
  filter(name %in% ego_g_member_names) %>% 
  mapview::mapview()

Getting Spatial Data

us_sf <- sf::st_as_sf(
  raster::getData(
    country = "United States",
    level = 1
  )
)

plot(us_sf$geometry)

missouri_sf <- us_sf %>%
  filter(NAME_1 == "Missouri")

mapview::mapview(missouri_sf)

Cropping by Spatial Geometries

missouri_members_sf <- all_members_sf %>%
  sf::st_crop(missouri_sf)

missouri_members_sf
## Simple feature collection with 24 features and 94 fields
## geometry type:  POINT
## dimension:      XY
## bbox:           xmin: -95.2499 ymin: 36.1867 xmax: -89.2157 ymax: 39.5594
## CRS:            EPSG:4326
## # A tibble: 24 x 95
##    member_id name  member_group_id email joined              ip_address
##        <int> <chr>           <int> <chr> <dttm>              <chr>     
##  1      9393 Blac…              13 smit… 2015-04-12 19:53:08 70.130.13…
##  2      2027 Seige              13 revs… 2012-11-21 17:05:10 71.34.207…
##  3       281 Mongo              13 mode… 2012-06-22 21:41:56 76.4.189.…
##  4      6247 Diom…              13 grey… 2013-09-13 11:33:43 216.106.2…
##  5       131 Conf…              13 cale… 2012-02-02 05:12:42 75.81.19.…
##  6      6321 Culi…              13 culi… 2013-11-08 05:08:30 65.26.125…
##  7      7730 crea…              13 rear… 2014-05-14 11:30:39 97.85.143…
##  8      9692 Redc…              13 truc… 2015-10-11 16:36:28 74.204.14…
##  9      9802 Erud…              13 davi… 2015-12-29 04:16:25 174.25.11…
## 10      9863 Jay                13 some… 2016-01-26 15:20:24 63.141.25…
## # … with 14 more rows, and 89 more variables: allow_admin_mails <lgl>,
## #   skin <int>, warn_level <int>, warn_lastwarn <int>, restrict_post <lgl>,
## #   bday_day <int>, bday_month <int>, bday_year <int>, msg_count_new <int>,
## #   msg_count_total <int>, msg_show_notification <lgl>, last_visit <dttm>,
## #   last_activity <dttm>, mod_posts <lgl>, auto_track <chr>, temp_ban <lgl>,
## #   mgroup_others <chr>, member_login_key_expire <dttm>,
## #   members_seo_name <chr>, members_cache <chr>, members_disable_pm <int>,
## #   failed_logins <chr>, members_profile_views <int>, members_pass_hash <chr>,
## #   members_pass_salt <chr>, members_bitoptions <int>, members_day_posts <chr>,
## #   notification_cnt <int>, posts <int>, title <chr>, time_offset <chr>,
## #   last_post <dttm>, view_sigs <lgl>, msg_count_reset <lgl>, dst_in_use <lgl>,
## #   login_anonymous <chr>, ignored_users <chr>, org_perm_id <chr>,
## #   member_login_key <chr>, members_auto_dst <lgl>, members_display_name <chr>,
## #   members_l_display_name <chr>, members_l_username <chr>,
## #   member_banned <lgl>, member_uploader <chr>, language <int>,
## #   failed_login_count <int>, pp_last_visitors <chr>, pp_main_photo <chr>,
## #   pp_main_width <int>, pp_main_height <int>, pp_thumb_photo <chr>,
## #   pp_thumb_width <int>, pp_thumb_height <int>,
## #   pp_setting_count_comments <lgl>, pp_reputation_points <int>,
## #   pp_gravatar <chr>, pp_photo_type <chr>, signature <chr>,
## #   fb_bwoptions <lgl>, tc_last_sid_import <chr>, tc_bwoptions <lgl>,
## #   pp_customization <chr>, timezone <chr>, pp_cover_photo <chr>,
## #   members_bitoptions2 <int>, create_menu <chr>, marked_site_read <int>,
## #   pp_cover_offset <int>, acp_skin <lgl>, acp_language <lgl>,
## #   member_title <chr>, member_posts <int>, member_last_post <int>,
## #   member_streams <chr>, photo_last_update <dttm>, msg_count_reset_at <dttm>,
## #   status <chr>, country <chr>, countryCode <chr>, region <chr>,
## #   regionName <chr>, city <chr>, zip <chr>, i.timezone <chr>, isp <chr>,
## #   org <chr>, as <chr>, geometry <POINT [°]>
missouri_members_sf %>% mapview::mapview()
all_member_ranges_sf <- merge(
  ironmarch:::.all_geocoded_ips_df,
  build_messages(as_tibble = FALSE),
  # build_members(as_tibble = FALSE),
  # ironmarch:::.get_geocodable_member_dfs(),
  by.x = "ip_address",
  by.y = "msg_ip_address"
  # nomatch = 0
  )[, .(msg_author_id, lon, lat)
    ] %>% 
  tibble::as_tibble() %>% 
  rename(member_id = msg_author_id) %>% 
  sf::st_as_sf(coords = c("lon", "lat"), crs = 4326L) %>% 
  group_by(member_id) %>%
  summarise() %>%
  inner_join(build_members(), by = "member_id") %>% 
  arrange(member_id)
all_member_ranges_sf
## Simple feature collection with 857 features and 83 fields
## geometry type:  GEOMETRY
## dimension:      XY
## bbox:           xmin: -157.8725 ymin: -42.885 xmax: 174.95 ymax: 65.3172
## CRS:            EPSG:4326
## # A tibble: 857 x 84
##    member_id                  geometry name  member_group_id email
##        <int>            <GEOMETRY [°]> <chr>           <int> <chr>
##  1         1 MULTIPOINT ((-71.1934 42… Алек…               4 slav…
##  2         2 MULTIPOINT ((-83.2107 42… Phal…              13 illu…
##  3         3 MULTIPOINT ((-122.7046 4… Bloo…              13 rene…
##  4         4 MULTIPOINT ((-0.6789 52.… Mier…              13 homi…
##  5         5   POINT (-1.5455 53.3929) Will…              14 tash…
##  6         6   POINT (-0.8284 52.2777) Inte…              13 mich…
##  7         7 MULTIPOINT ((-121.895 37… Dadd…              13 benj…
##  8         8 MULTIPOINT ((-122.136 47… Mr. …              13 elei…
##  9         9 MULTIPOINT ((8.40953 45.… Woma…              14 sol.…
## 10        10 MULTIPOINT ((-74.7524 40… Dene…              13 8056…
## # … with 847 more rows, and 79 more variables: joined <dttm>, ip_address <chr>,
## #   allow_admin_mails <lgl>, skin <int>, warn_level <int>, warn_lastwarn <int>,
## #   restrict_post <lgl>, bday_day <int>, bday_month <int>, bday_year <int>,
## #   msg_count_new <int>, msg_count_total <int>, msg_show_notification <lgl>,
## #   last_visit <dttm>, last_activity <dttm>, mod_posts <lgl>, auto_track <chr>,
## #   temp_ban <lgl>, mgroup_others <chr>, member_login_key_expire <dttm>,
## #   members_seo_name <chr>, members_cache <chr>, members_disable_pm <int>,
## #   failed_logins <chr>, members_profile_views <int>, members_pass_hash <chr>,
## #   members_pass_salt <chr>, members_bitoptions <int>, members_day_posts <chr>,
## #   notification_cnt <int>, posts <int>, title <chr>, time_offset <chr>,
## #   last_post <dttm>, view_sigs <lgl>, msg_count_reset <lgl>, dst_in_use <lgl>,
## #   login_anonymous <chr>, ignored_users <chr>, org_perm_id <chr>,
## #   member_login_key <chr>, members_auto_dst <lgl>, members_display_name <chr>,
## #   members_l_display_name <chr>, members_l_username <chr>,
## #   member_banned <lgl>, member_uploader <chr>, language <int>,
## #   failed_login_count <int>, pp_last_visitors <chr>, pp_main_photo <chr>,
## #   pp_main_width <int>, pp_main_height <int>, pp_thumb_photo <chr>,
## #   pp_thumb_width <int>, pp_thumb_height <int>,
## #   pp_setting_count_comments <lgl>, pp_reputation_points <int>,
## #   pp_gravatar <chr>, pp_photo_type <chr>, signature <chr>,
## #   fb_bwoptions <lgl>, tc_last_sid_import <chr>, tc_bwoptions <lgl>,
## #   pp_customization <chr>, timezone <chr>, pp_cover_photo <chr>,
## #   members_bitoptions2 <int>, create_menu <chr>, marked_site_read <int>,
## #   pp_cover_offset <int>, acp_skin <lgl>, acp_language <lgl>,
## #   member_title <chr>, member_posts <int>, member_last_post <int>,
## #   member_streams <chr>, photo_last_update <dttm>, msg_count_reset_at <dttm>
member_ranges_for_gg <- all_member_ranges_sf %>% 
  filter(member_id %in% 1:6) %>% 
  mutate(screen_name = name) %>% 
  sf::st_transform(crs = 3857L)
world_data <- rnaturalearthdata::sovereignty110 %>% 
  sf::st_as_sf() %>% tibble::as_tibble() %>% sf::st_as_sf() %>% 
  sf::st_transform(crs = 3857L) %>% 
  sf::st_crop(sf::st_buffer(member_ranges_for_gg, 2e5))

member_ranges_gg <- member_ranges_for_gg %>% 
  ggplot() +
  geom_sf(data = world_data) +
  geom_sf(aes(color = screen_name), size = 5, show.legend = "point") +
  guides(color = guide_legend(title = "member_id")) +
  theme_minimal() +
  theme(legend.position = "bottom")

member_ranges_gg

member_ranges_gg + facet_wrap(~ screen_name, ncol = 2) + guides(color = FALSE)

all_member_ranges_sf %>% 
  filter(member_id == 1) %>%  # Alexander Slavros
  # sf::st_centroid() %>% 
  mapview::mapview()